// StatusDlg.cpp : implementation file
//

#include "stdafx.h"
#include "RMSServer.h"
#include "RMSServerDlg.h"
#include "StatusDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


///#define GET_SERVER_DLG			((CRMSServerDlg*)AfxGetMainWnd())
#define GET_BASE_SERVER			(GET_SERVER_DLG->BaseServer)
#define getHomePath				GET_SERVER_DLG->getHomePath
#define saveHomePath			GET_SERVER_DLG->saveHomePath

/////////////////////////////////////////////////////////////////////////////
// CRecordDlg dialog

#define MIN_FREE_SPACE 0x5

CRecordDlg::CRecordDlg(CWnd* pParent/*=NULL*/)
	: CDialog(CRecordDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CRecordDlg)
	m_strBitrate = _T("");
	m_strDiskSpace = _T("");
	m_strFileName = _T("");
	m_strFileSize = _T("");
	m_strFrameRate = _T("10");
	m_strNewFrameRate = _T("");
	//}}AFX_DATA_INIT

	ASSERT(pParent != NULL);

	m_pParent = pParent;
	m_nID = CRecordDlg::IDD;

	m_file = NULL;

	m_bSpace = FALSE;
}


void CRecordDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CRecordDlg)
	DDX_Control(pDX, IDC_NEWFRAMERATE, m_editFrameRate);
	DDX_Text(pDX, IDC_BITRATE, m_strBitrate);
	DDX_Text(pDX, IDC_DISKSPACE, m_strDiskSpace);
	DDX_Text(pDX, IDC_FILENAME, m_strFileName);
	DDX_Text(pDX, IDC_FILESIZE, m_strFileSize);
	DDX_Text(pDX, IDC_FRAMERATE, m_strFrameRate);
	DDX_Text(pDX, IDC_NEWFRAMERATE, m_strNewFrameRate);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CRecordDlg, CDialog)
	//{{AFX_MSG_MAP(CRecordDlg)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_SET, OnSet)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRecordDlg message handlers

BOOL CRecordDlg::CreateDlg() 
{
	return CDialog::Create(m_nID, m_pParent);
}

void CRecordDlg::PostNcDestroy() 
{
	if(m_file)
	{
		fclose(m_file);
		m_file = NULL;
	}

	delete this;	
}

BOOL CRecordDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

	m_nStoredBitrate = 0;
	m_timeStart = 0;
	m_timeEnd = 0;
	m_dwDelta = 0;
	m_fps = 0;
	m_lTotalStoredData = 0;

// Load from registry (Frame Rate)

	LONG lnRes;
	HKEY hKey;
	DWORD lLen;
	DWORD dwType;
	DWORD value;

	lnRes = RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Streambox Everywhere\\Settings",0,KEY_ALL_ACCESS,&hKey);
	if(ERROR_SUCCESS == lnRes)
	{
		lLen = sizeof(DWORD);
		lnRes = RegQueryValueEx(hKey,"Stored Frame Rate",0,&dwType,(BYTE*)&(value),&lLen);
		if(ERROR_SUCCESS == lnRes)
		{
			m_nStoredFrameRate = value;
		}
		else
		{
			m_nStoredFrameRate = 10;
		}
		RegCloseKey(hKey);
	}
	else
	{
		m_nStoredFrameRate = 10;
	}

	m_strNewFrameRate.Format("%d",m_nStoredFrameRate);

	int nTotalFreeSpace;

	if(GetCurrentDirectory(255, m_szBuffer))
	{
		FARPROC pGetDiskFreeSpaceEx = GetProcAddress( GetModuleHandle("kernel32.dll"),
								 "GetDiskFreeSpaceExA");

		if(pGetDiskFreeSpaceEx)
		{
			if(GetDiskFreeSpaceEx(m_szBuffer,
						(PULARGE_INTEGER)&m_i64FreeBytesToCaller,
						(PULARGE_INTEGER)&m_i64TotalBytes,
						(PULARGE_INTEGER)&m_i64FreeBytes))
			{
				nTotalFreeSpace = (int) (m_i64FreeBytesToCaller / (1024 * 1024));
				m_strDiskSpace.Format("%i",nTotalFreeSpace);
			}
			else
			{
				m_strDiskSpace = _T("not defined");
			}
		}
		else
		{
			if(GetDiskFreeSpace (NULL, 
						&m_dwSectPerClust, 
						&m_dwBytesPerSect,
						&m_dwFreeClusters, 
						&m_dwTotalClusters))
			{
				nTotalFreeSpace = (int) (m_dwSectPerClust * m_dwBytesPerSect * m_dwFreeClusters / (1024 * 1024));
				m_strDiskSpace.Format("%i",nTotalFreeSpace);
			}
			else
			{
				m_strDiskSpace = _T("not defined");
			}
		}
	}
	else
	{
		if(GetDiskFreeSpace (NULL, 
					&m_dwSectPerClust, 
					&m_dwBytesPerSect,
					&m_dwFreeClusters, 
					&m_dwTotalClusters))
		{
			nTotalFreeSpace = (int) (m_dwSectPerClust * m_dwBytesPerSect * m_dwFreeClusters / (1024 * 1024));
			m_strDiskSpace.Format("%i",nTotalFreeSpace);
		}
		else
		{
			m_strDiskSpace = _T("not defined");
		}
	}

	if((nTotalFreeSpace < MIN_FREE_SPACE) && nTotalFreeSpace)
	{
		MessageBox("Warning! Hard disk is full.", "RMS Server", MB_OK | MB_ICONWARNING);

		GET_BASE_SERVER.SetRecordState(FALSE);
		
		if(m_file)
		{
			fclose(m_file);
			m_file = NULL;
		}
		((CRMSServerDlg*)AfxGetMainWnd())->SetDlgItemText(IDSAVE,"Record");
		m_bSpace = FALSE;
		return FALSE;
	}
#ifdef _CYCLIC_BUFFER_
	CTime timeTemp;
	GET_BASE_SERVER.GetServerTime(timeTemp);

	m_strFile = timeTemp.Format("%b%d%Y.rms");
#endif
	
	HANDLE hFile; 
#ifdef _CYCLIC_BUFFER_
	int cycle;
	CTime timeFile;

	cycle = GET_BASE_SERVER.GetRecordCycle();
	GET_BASE_SERVER.GetServerTime(timeFile);
	CTimeSpan timeSpan(1,0,0,0);
	CString strFile;
	int nFileSizeMB = 0;

	for(int j = 0; j< cycle; j++)
	{
		strFile = timeFile.Format("%b%d%Y.rms");

		hFile = CreateFile((LPCTSTR)strFile,           // open MYFILE.TXT 
							0/*GENERIC_READ*/,              // open for reading 
							0/*FILE_SHARE_READ*/,           // share for reading 
							NULL,                      // no security 
							OPEN_EXISTING,             // existing file only 
							FILE_ATTRIBUTE_NORMAL,     // normal file 
							NULL);                     // no attr. template 

		if (hFile != INVALID_HANDLE_VALUE) 
		{ 
			DWORD dwFileSize;

			dwFileSize = GetFileSize(hFile, NULL);
			if((int)dwFileSize != -1)
			{
				nFileSizeMB += (int)((float)(dwFileSize) / (1024.0*1024.0) + .5);
			}
			CloseHandle(hFile);
		}

		timeFile -= timeSpan;
	}
	if(nFileSizeMB)
	{
		m_strFileSize.Format("%d",nFileSizeMB);
	}
	else
	{
		m_strFileSize = _T("0");
	}
#else
 	hFile = CreateFile("stored_video.rms",           // open MYFILE.TXT 
						0/*GENERIC_READ*/,              // open for reading 
						0/*FILE_SHARE_READ*/,           // share for reading 
						NULL,                      // no security 
						OPEN_EXISTING,             // existing file only 
						FILE_ATTRIBUTE_NORMAL,     // normal file 
						NULL);                     // no attr. template 

	if (hFile != INVALID_HANDLE_VALUE) 
	{ 
		DWORD dwFileSize;
		int nFileSizeMB;

		dwFileSize = GetFileSize(hFile, NULL);
		if(dwFileSize != -1)
		{
			nFileSizeMB = (int)((float)(dwFileSize) / (1024.0*1024.0) + .5);
			m_strFileSize.Format("%d",nFileSizeMB);

		}
		else
		{
			m_strFileSize = _T("not definded");
		}
		CloseHandle(hFile);
	}
	else
	{
		m_strFileSize = _T("not definded");
	}
#endif
		

	
	m_strBitrate = _T("0");
#ifdef _CYCLIC_BUFFER_
	m_strFileName = m_strFile;
#else
	m_strFileName = _T("stored_video.rms");
#endif
	m_strFrameRate = _T("0");

	UpdateData(FALSE);

	CString hp = getHomePath();
#ifdef _CYCLIC_BUFFER_
	hp += _T("\\");
	hp += m_strFile;
	m_file = _tfopen(hp, _T("ab"));
#else
	hp += _T("\\stored_video.rms");
	m_file = _tfopen(hp, _T("ab"));
#endif

	SetTimer(1, 1000, 0);
	SetTimer(2, 15000, 0);
	SetTimer(3, 1000/m_nStoredFrameRate, 0);

	m_bSpace = TRUE;

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CRecordDlg::OnTimer(UINT nIDEvent) 
{
	int nTotalFreeSpace = 0;
	HANDLE hFile; 
#ifdef _CYCLIC_BUFFER_
	int cycle;
	CTime timeFile;
	CTimeSpan timeSpan(1,0,0,0);
	CString strFile;
	int nFileSizeMB;
	int j;
#endif


	UpdateData(TRUE);

	switch(nIDEvent)
	{
	case 1:
		m_strBitrate.Format("%.1f",(float)m_nStoredBitrate);
		m_strFrameRate.Format("%d",m_nStoredFrameRate);
#ifdef _CYCLIC_BUFFER_
		m_strFileName = m_strFile;
#endif
		UpdateData(FALSE);
		break;
	case 2:
#ifdef _CYCLIC_BUFFER_
		cycle = GET_BASE_SERVER.GetRecordCycle();
		GET_BASE_SERVER.GetServerTime(timeFile);
		nFileSizeMB = 0;

		for(j = 0; j<cycle ; j++)
		{
			strFile = timeFile.Format("%b%d%Y.rms");

			hFile = CreateFile((LPCTSTR)strFile,           // open MYFILE.TXT 
								0/*GENERIC_READ*/,              // open for reading 
								0/*FILE_SHARE_READ*/,           // share for reading 
								NULL,                      // no security 
								OPEN_EXISTING,             // existing file only 
								FILE_ATTRIBUTE_NORMAL,     // normal file 
								NULL);                     // no attr. template 

			if (hFile != INVALID_HANDLE_VALUE) 
			{ 
				DWORD dwFileSize;

				dwFileSize = GetFileSize(hFile, NULL);
				if((int)dwFileSize != -1)
				{
					nFileSizeMB += (int)((float)(dwFileSize) / (1024.0*1024.0) + .5);
				}
				CloseHandle(hFile);
			}

			timeFile -= timeSpan;
		}
		if(nFileSizeMB)
		{
			m_strFileSize.Format("%d",nFileSizeMB);
		}
		else
		{
			m_strFileSize = _T("0");
		}
#else
 		hFile = CreateFile("stored_video.rms",           // open MYFILE.TXT 
							0/*GENERIC_READ*/,              // open for reading 
							0/*FILE_SHARE_READ*/,           // share for reading 
							NULL,                      // no security 
							OPEN_EXISTING,             // existing file only 
							FILE_ATTRIBUTE_NORMAL,     // normal file 
							NULL);                     // no attr. template 
 
		if (hFile != INVALID_HANDLE_VALUE) 
		{ 
			DWORD dwFileSize;
			int nFileSizeMB;

			dwFileSize = GetFileSize(hFile, NULL);
			if(dwFileSize != -1)
			{
				nFileSizeMB = (int)((float)(dwFileSize) / (1024.0*1024.0) + .5);
				m_strFileSize.Format("%d",nFileSizeMB);

			}
			else
			{
				m_strFileSize = _T("not definded");
			}
			CloseHandle(hFile);
		}
		else
		{
			m_strFileSize = _T("not definded");
		}
#endif

		if(GetCurrentDirectory(255, m_szBuffer))
		{
			FARPROC pGetDiskFreeSpaceEx = GetProcAddress( GetModuleHandle("kernel32.dll"),
									 "GetDiskFreeSpaceExA");

			if(pGetDiskFreeSpaceEx)
			{
				if(GetDiskFreeSpaceEx(m_szBuffer,
							(PULARGE_INTEGER)&m_i64FreeBytesToCaller,
							(PULARGE_INTEGER)&m_i64TotalBytes,
							(PULARGE_INTEGER)&m_i64FreeBytes))
				{
					nTotalFreeSpace = (int) (m_i64FreeBytesToCaller / (1024 * 1024));
					m_strDiskSpace.Format("%i",nTotalFreeSpace);
				}
				else
				{
					m_strDiskSpace = _T("not defined");
				}
			}
			else
			{
				if(GetDiskFreeSpace (NULL, 
							&m_dwSectPerClust, 
							&m_dwBytesPerSect,
							&m_dwFreeClusters, 
							&m_dwTotalClusters))
				{
					nTotalFreeSpace = (int) (m_dwSectPerClust * m_dwBytesPerSect * m_dwFreeClusters / (1024 * 1024));
					m_strDiskSpace.Format("%i",nTotalFreeSpace);
				}
				else
				{
					m_strDiskSpace = _T("not defined");
				}
			}
		}
		else
		{
			if(GetDiskFreeSpace (NULL, 
						&m_dwSectPerClust, 
						&m_dwBytesPerSect,
						&m_dwFreeClusters, 
						&m_dwTotalClusters))
			{
				nTotalFreeSpace = (int) (m_dwSectPerClust * m_dwBytesPerSect * m_dwFreeClusters / (1024 * 1024));
				m_strDiskSpace.Format("%i",nTotalFreeSpace);
			}
			else
			{
				m_strDiskSpace = _T("not defined");
			}
		}
		UpdateData(FALSE);
		if((nTotalFreeSpace < MIN_FREE_SPACE) && nTotalFreeSpace)
		{
			KillTimer(1);
			KillTimer(2);
			KillTimer(3);

			MessageBox("Warning! Hard disk is full.", "RMS Server", MB_OK | MB_ICONWARNING);

			GET_BASE_SERVER.SetRecordState(FALSE);
			
			if(m_file)
			{
				fclose(m_file);
				m_file = NULL;
			}
			((CRMSServerDlg*)AfxGetMainWnd())->SetDlgItemText(IDSAVE,"Record");
			EndDialog(IDOK);
		}
		break;
	case 3:
#ifdef _CYCLIC_BUFFER_
		if(GET_BASE_SERVER.DateIsChanged())
		{
			if(m_file)
			{
				fclose(m_file);
				m_file = NULL;
			}
			CTime timeTemp;
			GET_BASE_SERVER.GetServerTime(timeTemp);
			m_strFile = timeTemp.Format("%b%d%Y.rms");
			CString hp = getHomePath();
			hp += "\\";
			hp += m_strFile;
			m_file = fopen(hp, "ab");
		}
#endif
		if(GET_BASE_SERVER.GetRecordState())
		{
			EnterCriticalSection(GET_SERVER_DLG->pCriticalData);

			m_timeEnd = timeGetTime();
			m_dwDelta = m_dwDelta + (m_timeEnd - m_timeStart);

			if(m_timeEnd - m_timeStart)
			{
				m_nCurrentFrameRate = (int)((1000.0)/(float)(m_timeEnd - m_timeStart) + 0.5);
			}
			else
			{
				m_nCurrentFrameRate = 0;
			}

			m_timeStart = timeGetTime();

			if(m_dwDelta > 1000)
			{
				m_nStoredFrameRate = (int)(((float)m_fps * 1000.0) / (float)m_dwDelta + .5);
				m_nStoredBitrate = (int)((((float)m_lTotalStoredData * 8.0 / 1024.0) * 1000.0 ) / (float)m_dwDelta + .5);
				m_fps = 0;
				m_dwDelta = 0;
				m_lTotalStoredData = 0;
			}
			m_fps++;

			m_dwLen = 0;

			if(m_file)
			{
				m_time = CTime::GetCurrentTime();

				m_dwTag = TAG_STOREDDATA;
				m_dwLen += sizeof(DWORD);
				fwrite(&m_dwTag, sizeof(DWORD), 1, m_file);

				m_dwTag = TAG_TIMEMARK;
				m_dwLen += sizeof(DWORD);
				fwrite(&m_dwTag, sizeof(DWORD), 1, m_file);

				TimeMark tm;

				tm.dwYear = m_time.GetYear();
				tm.bMonth = m_time.GetMonth();
				tm.bDay = m_time.GetDay();
				tm.bHour = m_time.GetHour();
				tm.bMinute = m_time.GetMinute();
				tm.bSecond = m_time.GetSecond();
				m_dwLen += sizeof(TimeMark);
				fwrite(&tm, sizeof(TimeMark), 1, m_file);

				m_str = m_time.Format("%H:%M:%S");
				m_sizeStr = m_str.GetLength()+1;

				m_dwTag = TAG_STOREDTIME_v01;
				m_dwLen += sizeof(DWORD);
				fwrite(&m_dwTag, sizeof(DWORD), 1, m_file);
				m_dwLen += sizeof(DWORD);
				fwrite(&m_sizeStr, sizeof(DWORD), 1, m_file);
				m_dwLen += m_sizeStr;
				fwrite((LPCTSTR)m_str, sizeof(BYTE), m_sizeStr, m_file);

				m_str = m_time.Format("%B %d,%Y");
				m_sizeStr = m_str.GetLength()+1;

				m_dwTag = TAG_STOREDDATE_v01;
				m_dwLen += sizeof(DWORD);
				fwrite(&m_dwTag, sizeof(DWORD), 1, m_file);
				m_dwLen += sizeof(DWORD);
				fwrite(&m_sizeStr, sizeof(DWORD), 1, m_file);
				m_dwLen += m_sizeStr;
				fwrite((LPCTSTR)m_str, sizeof(BYTE), m_sizeStr, m_file);

				m_dwTag = TAG_RMSSTOREDVIDEO_v01;
				m_dwLen += sizeof(DWORD);
				fwrite(&m_dwTag, sizeof(DWORD), 1, m_file);
				*GET_SERVER_DLG->pSzVideo += sizeof(int);
				m_dwLen += sizeof(DWORD);
				m_dwLen += *GET_SERVER_DLG->pSzVideo;
				fwrite(GET_SERVER_DLG->pSzVideo, sizeof(DWORD), 1, m_file);
				fwrite(&m_nCurrentFrameRate,sizeof(int), 1, m_file);
				*GET_SERVER_DLG->pSzVideo -= sizeof(int);
				fwrite(GET_SERVER_DLG->dtVideo, sizeof(BYTE), *GET_SERVER_DLG->pSzVideo, m_file);

				m_dwTag = TAG_SIZE;
				fwrite(&m_dwTag, sizeof(DWORD), 1, m_file);
				fwrite(&m_dwLen, sizeof(DWORD), 1, m_file);

				fflush(m_file);
				m_lTotalStoredData += m_dwLen;
			}
			LeaveCriticalSection(GET_SERVER_DLG->pCriticalData);
		}
	default:
		break;
	}
	
	CDialog::OnTimer(nIDEvent);
}

void CRecordDlg::SaveCameraAudio(int nCameraID, BYTE n)
{
}

void CRecordDlg::OnCancel() 
{
	if(m_file)
	{
		fclose(m_file);
		m_file = NULL;
	}

	GET_BASE_SERVER.SetRecordState(FALSE);
	((CRMSServerDlg*)AfxGetMainWnd())->SetDlgItemText(IDSAVE,"Record");
	
	CDialog::OnCancel();
}

void CRecordDlg::OnSet() 
{
	UpdateData(TRUE);

	m_nNewFrameRate = atoi((LPCTSTR)m_strNewFrameRate);
	if((m_nNewFrameRate > 0) && (m_nNewFrameRate <= 30))
	{
		KillTimer(3);
		SetTimer(3, 1000/m_nNewFrameRate, 0);

// Update registry
		LONG lnRes;
		HKEY hKey;
		DWORD dwDisp;
		DWORD value;

		lnRes = RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Streambox Everywhere\\Settings",0,KEY_ALL_ACCESS,&hKey);
		if(ERROR_SUCCESS != lnRes)
		{
			lnRes = RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Streambox Everywhere\\Settings",0,NULL,
				REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp);
			if(ERROR_SUCCESS != lnRes)
			{
				RegCloseKey(hKey);
				return;
			}
		}

		value = (DWORD)(m_nNewFrameRate);
		lnRes = RegSetValueEx(hKey,"Stored Frame Rate",NULL,REG_DWORD,(BYTE*)&(value),sizeof(DWORD));

		RegCloseKey(hKey);
	}
	else
	{
		MessageBox("Invalid Frame Rate.","RMS Server", MB_OK | MB_ICONWARNING);
		m_strNewFrameRate.Format("%d", m_nStoredFrameRate);
		UpdateData(FALSE);
		m_editFrameRate.SetFocus();
	}
}
